package com.yanqu.road.server.manger.activity.chefduel;

import com.yanqu.road.dao.impl.player.UserChefDuelDaoImpl;
import com.yanqu.road.dao.impl.player.UserCommonActivityDataDaoImpl;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.chefduel.ChefDuelData;
import com.yanqu.road.entity.activity.chefduel.process2.ChefDuel2Dish;
import com.yanqu.road.entity.activity.chefduel.process2.ChefDuel2DishConfig;
import com.yanqu.road.entity.activity.chefduel.process2.ChefDuel2Spoon;
import com.yanqu.road.entity.activity.cookboy.process2.PickDishRes;
import com.yanqu.road.entity.autodata.chefduel2.ChefDuel2AutoJoinSpoon;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.enums.activity.chefDuel.eChefDuelActivityType;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eMailType;
import com.yanqu.road.entity.language.LanguageType;
import com.yanqu.road.entity.log.LogChefDuel2FinishFood;
import com.yanqu.road.entity.log.LogChefDuel2PickFood;
import com.yanqu.road.entity.log.chefduel.LogChefDuelPromotion;
import com.yanqu.road.entity.player.UserBagItem;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.player.UserInfo;
import com.yanqu.road.entity.relatives.RelativesInfo;
import com.yanqu.road.entity.task.args.RelationActivityUnionRiseRankArgs;
import com.yanqu.road.entity.task.args.UnionRiseRankArgs;
import com.yanqu.road.entity.union.UnionMember;
import com.yanqu.road.entity.union.cross.CrossUnionMember;
import com.yanqu.road.logic.activity.chefduel.ChefDuel2Config;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.pb.chefduel.ChefDuelProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.chefduel.ChefDuelModule;
import com.yanqu.road.server.gameplayer.module.player.BagModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.gameplayer.module.relatives.RelativesModule;
import com.yanqu.road.server.logic.mail.MailManager;
import com.yanqu.road.server.manger.MultipleLanguageMgr;
import com.yanqu.road.server.manger.ServerLanguageMgr;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.RelationActivityMgr;
import com.yanqu.road.server.manger.config.GoodsMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.union.CrossUnionMgr;
import com.yanqu.road.server.pb.PlayerPb;
import com.yanqu.road.server.protocol.CrossProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class ChefDuel2 {

    private Logger logger = LogManager.getLogger(ChefDuel2.class.getName());

    private final Map<Long,Object> lockMap = new ConcurrentHashMap<>();
    
    private ActivityInfo activityInfo;

    private Random random = new Random();

    public boolean init() {
        return reload();
    }

    public ActivityInfo getActivityInfo() {
        return activityInfo;
    }

    public void setActivityInfo(ActivityInfo activityInfo) {
        this.activityInfo = activityInfo;
    }

    public ChefDuel2(ActivityInfo activityInfo) {
        this.activityInfo = activityInfo;
    }

    //用户id 用户数据
    private Map<Long, ChefDuelData> chefDuelDataMap = new ConcurrentHashMap<>();

    private List<ChefDuelData> needAddChefDuelList = new ArrayList<>();

    private List<ChefDuelData> needUpdateChefDuelList = new ArrayList<>();

    private long lastUploadTime = System.currentTimeMillis();

    //正在发菜场景的人
    private Map<Long,List<Long>> sceneUserMap = new ConcurrentHashMap<>();

    boolean acOverRecovery = false;

    private long lastChekDishStatusTime;

    private Map<Long, ChefDuel2AutoJoinSpoon> autoJoinSpoonMap = new ConcurrentHashMap<>(); // 自动回访汤勺


    public Object getLock(long userId){
        synchronized (lockMap){
            if(!lockMap.containsKey(userId)){
                lockMap.put(userId,new Object());
            }
            return lockMap.get(userId);
        }
    }

    public boolean isSceneUser(long userId,long openBanquetUserId){
        for(Long inUserId : sceneUserMap.get(openBanquetUserId)){
            if(inUserId == userId){
                return true;
            }
        }
        return false;
    }
    public Map<Long, ChefDuelData> getWindUpUserChefDuelMap(List<ChefDuelProto.CrossChefDuelWindUpCookerTempMsg> userIdList){
        Map<Long,ChefDuelData> res = new ConcurrentHashMap<>();
        for(ChefDuelProto.CrossChefDuelWindUpCookerTempMsg tempMsg : userIdList){
            if(chefDuelDataMap.containsKey(tempMsg.getUserId())){
                res.put(tempMsg.getUserId(), chefDuelDataMap.get(tempMsg.getUserId()));
            }
        }
        return res;
    }

    //晋级玩家数据生成
    public boolean windUpChefDuel(List<ChefDuelProto.CrossChefDuelWindUpCookerTempMsg> userIdList){
        boolean isUpdate = false;
        for(ChefDuelProto.CrossChefDuelWindUpCookerTempMsg tempMsg : userIdList){
            if(!chefDuelDataMap.containsKey(tempMsg.getUserId())){
                ChefDuelData value = initChefDuel2(tempMsg.getUserId());
                chefDuelDataMap.put(tempMsg.getUserId(), value);
            }
            ChefDuelData chefDuelData = chefDuelDataMap.get(tempMsg.getUserId());
            if(chefDuelData.isAble()){
                continue;
            }
            chefDuelData.setPreRank(tempMsg.getRank());
            chefDuelData.setAble(true);
            isUpdate = true;
            synchronized (needUpdateChefDuelList){
                if(!needUpdateChefDuelList.contains(chefDuelData)){
                    needUpdateChefDuelList.add(chefDuelData);
                }
            }
            GamePlayer player = GamePlayerMgr.getOnlinePlayer(tempMsg.getUserId());
            if(player != null){
                player.getModule(ChefDuelModule.class).syncSelfDishTable(activityInfo.getActivityId(),"");
            }
            AutoLogMgr.add(new LogChefDuelPromotion(activityInfo.getActivityId(),
                    chefDuelData.getUserId(),
                    2,
                    tempMsg.getScore(),
                    tempMsg.getRank(),
                    0));
        }
        return isUpdate;
    }

    public int worship(long userId){
        Object locker = getLock(userId);
        synchronized (locker){
            ChefDuelData chefDuelData = chefDuelDataMap.get(userId);
            if(chefDuelData.isWorship()){
                return GameErrorCode.E_CHEF_DUEL_FOOD_IS_WORSHIP;
            }
            GamePlayer gamePlayer = GamePlayerMgr.getOnlinePlayer(userId);
            if(gamePlayer != null){
                chefDuelData.setWorship(true);
                synchronized (needUpdateChefDuelList){
                    if(!needUpdateChefDuelList.contains(chefDuelData)){
                        needUpdateChefDuelList.add(chefDuelData);
                    }
                }
                gamePlayer.getModule(CurrencyModule.class).addCurrency(ChefDuelActivityMgr.getWorship2Reward(activityInfo.getActivityId()), eLogMoneyType.ChefDuel,eLogMoneyType.CrossChefDuelActivityWorship);
            }
        }
        return 0;
    }

    public void addSceneUser(long userId,long openBanquetUserId){
        if(!sceneUserMap.containsKey(openBanquetUserId)){
            sceneUserMap.put(openBanquetUserId,new ArrayList<>());
        }
        for(List<Long> userIdList : sceneUserMap.values()){
            userIdList.remove(userId);
        }
        sceneUserMap.get(openBanquetUserId).add(userId);
    }

    public void removeSceneUser(long userId,long openBanquetUserId){
        if(sceneUserMap.containsKey(openBanquetUserId)){
            sceneUserMap.get(openBanquetUserId).remove(userId);
        }
    }

    public List<Long> getSceneUser(long openBanquetUserId){
        if(sceneUserMap.containsKey(openBanquetUserId)){
            return new ArrayList<>(sceneUserMap.get(openBanquetUserId));
        }
        return new ArrayList<>();
    }

    public void chefDuel2RobotBackMsg(ChefDuelProto.CrossChefDuel2RobotJoinBanquetMsg msg){
        long userId = msg.getHomeUserId();
        Object locker = getLock(userId);
        synchronized (locker){
            ChefDuelData chefDuelData = chefDuelDataMap.get(userId);
            Map<Integer, ChefDuel2Dish> chefDuel2DishMap = chefDuelData.getFinishDishMap();
            ChefDuel2Dish chefDuel2Dish = chefDuel2DishMap.get(msg.getUserDishId());
            if(chefDuel2Dish.getStatus() == 0 || chefDuel2Dish.getStatus() == 2 || chefDuel2Dish.getStatus() == 3){
                logger.error(userId + "玩家的" + chefDuel2Dish.getDishId() + "菜已经完成");
                return;
            }
            GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
            chefDuelData.setAllIntegral(chefDuelData.getAllIntegral() + msg.getIntegral());
            chefDuelData.setRankTime(System.currentTimeMillis());
            chefDuel2Dish.setStatus(2);
            chefDuel2Dish.setIntegral(msg.getAllIntegral());
            chefDuel2Dish.setTableId(msg.getTableId());
            chefDuelData.setFinishDishMap(chefDuel2DishMap);
            if(player != null){
                int integralId = ChefDuelActivityMgr.getChefDuel2IntegralItemId(activityInfo.getActivityId());
                String reward = integralId + "=" + msg.getIntegral();
                player.getModule(CurrencyModule.class).addCurrency(reward,eLogMoneyType.ChefDuel,eLogMoneyType.CrossChefDuel2JoinBanquetOwnerReward);
                player.getModule(ChefDuelModule.class).syncSelfDishTable(activityInfo.getActivityId(),"");
            }else{
                chefDuelData.setIntegral(chefDuelData.getIntegral() + msg.getIntegral());
            }
            synchronized (needUpdateChefDuelList){
                if(!needUpdateChefDuelList.contains(chefDuelData)){
                    needUpdateChefDuelList.add(chefDuelData);
                }
            }
            UserInfo userInfo = UserMgr.getUserInfo(userId);
            RelationActivityMgr.conditionNotify(activityInfo.getActivityId(),userId, eGamePlayerEventType.ChefDuel2IntegralUserCrossRank.getValue(),
                    new RelationActivityUnionRiseRankArgs(UnionRiseRankArgs.NOTIFY_TYPE_NORMAL, BigInteger.valueOf(msg.getIntegral()),userInfo.getUnionUid(), activityInfo.getActivityId()));

        }
    }


    public void syncHorseNotice(ChefDuelProto.CrossChefDuel2HorseSyncServerMsg msg){
        List<GamePlayer> gamePlayerList = GamePlayerMgr.getAllOnlinePlayer();
        for(GamePlayer player : gamePlayerList){
            ChefDuelProto.ChefDuel2horseRaceLampSyncMsg.Builder userHorseMsg = ChefDuelProto.ChefDuel2horseRaceLampSyncMsg.newBuilder();
            for(ChefDuelProto.CrossChefDuel2HorseNoticeMsg noticeMsg : msg.getNoticeListList()){
                if(noticeMsg.getUserId() != player.getUserId()){
                    ChefDuelProto.ChefDuel2horseRaceLampTempMsg.Builder tempMsg = ChefDuelProto.ChefDuel2horseRaceLampTempMsg.newBuilder();
                    tempMsg.setUserId(noticeMsg.getUserId());
                    tempMsg.setDishId(noticeMsg.getDishId());
                    tempMsg.setUserInfo(noticeMsg.getPlayerBaseData());
                    userHorseMsg.addNoticeList(tempMsg);
                }
            }
            player.sendPacket(Protocol.U_CROSS_CHEF_DUEL2_HORSE_NOTICE_SYNC, userHorseMsg);
        }
    }

    public void syncTable(ChefDuelProto.CrossChefDuel2TableSyncMsg msg){
        ChefDuelProto.ChefDuel2UserIdTableRespMsg.Builder userTableMsg = ChefDuelProto.ChefDuel2UserIdTableRespMsg.newBuilder(msg.getUserTable());
        userTableMsg.setIsSync(true);
        List<Long> notOnlineUserId = new ArrayList<>();
        List<Long> userList = getSceneUser(msg.getUserId());
        for(long userId : userList){
            GamePlayer gamePlayer = GamePlayerMgr.getOnlinePlayer(userId);
            if(gamePlayer != null){
                gamePlayer.sendPacket(Protocol.U_CHEF_DUEL2_GET_TABLE_INFO, userTableMsg);
            }else{
                notOnlineUserId.add(userId);
            }
        }
        for(long userId : notOnlineUserId){
            userList.remove(userId);
        }
    }

    public void syncFoodServe(long userId, ChefDuelProto.ChefDuel2OpenTableRespMsg msg){
        if(chefDuelDataMap.containsKey(userId)){
            ChefDuelData chefDuelData = chefDuelDataMap.get(userId);
            Map<Integer,ChefDuel2Dish> chefDuel2DishMap = chefDuelData.getFinishDishMap();
            for(ChefDuelProto.CrossChefDuel2FoodTableIdMsg oneMsg : msg.getFoodListList()){
                if(chefDuel2DishMap.containsKey(oneMsg.getUserDishId())){
                    ChefDuel2Dish chefDuel2Dish = chefDuel2DishMap.get(oneMsg.getUserDishId());
                    chefDuel2Dish.setTableId(oneMsg.getTableId());

                    ChefDuel2DishConfig chefDuel2DishConfig = ChefDuelActivityMgr.getDishConfig(activityInfo.getActivityId(), chefDuel2Dish.getDishId());
                    int quality = 0;
                    if(chefDuel2DishConfig != null){
                        quality = chefDuel2DishConfig.getQuality();
                    }
                    AutoLogMgr.add(new LogChefDuel2FinishFood(
                            activityInfo.getActivityId(),
                            userId,
                            chefDuel2Dish.getIndex(),
                            chefDuel2Dish.getDishId(),
                            quality,
                            0,
                            chefDuelData.getCampId(),
                            0, 0));
                }
            }
            chefDuelData.setFinishDishMap(chefDuel2DishMap);
            synchronized (needUpdateChefDuelList){
                if(!needUpdateChefDuelList.contains(chefDuelData)){
                    needUpdateChefDuelList.add(chefDuelData);
                }
            }
            GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
            if(player != null){
                player.getModule(ChefDuelModule.class).syncSelfDishTable(activityInfo.getActivityId(),"");
            }
        }
    }

    public void backFoodServe(long userId, ChefDuelProto.ChefDuel2OpenTableRespMsg msg){
        if(chefDuelDataMap.containsKey(userId)){
            ChefDuelData chefDuelData = chefDuelDataMap.get(userId);
            Map<Integer,ChefDuel2Dish> chefDuel2DishMap = chefDuelData.getFinishDishMap();
            for(ChefDuelProto.CrossChefDuel2FoodTableIdMsg oneMsg : msg.getFoodListList()){
                if(chefDuel2DishMap.containsKey(oneMsg.getUserDishId())){
                    if(chefDuel2DishMap.get(oneMsg.getUserDishId()).getStatus() == 1){
                        chefDuel2DishMap.get(oneMsg.getUserDishId()).setStatus(0);
                    }
                }
            }
            chefDuelData.setFinishDishMap(chefDuel2DishMap);
            synchronized (needUpdateChefDuelList){
                if(!needUpdateChefDuelList.contains(chefDuelData)){
                    needUpdateChefDuelList.add(chefDuelData);
                }
            }
            GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
            if(player != null){
                player.getModule(ChefDuelModule.class).syncSelfDishTable(activityInfo.getActivityId(),"");
            }
        }
    }

    public void syncCooker(ChefDuelProto.CrossChefDuel2CookerSyncMsg msg){
        for(ChefDuelData chefDuelData : chefDuelDataMap.values()){
            if(chefDuelData.isAble()){
                GamePlayer player = GamePlayerMgr.getOnlinePlayer(chefDuelData.getUserId());
                if(player != null){
                    ChefDuelProto.ChefDuel2CookerRespMsg.Builder userTableSyncMsg = ChefDuelProto.ChefDuel2CookerRespMsg.newBuilder();
                    userTableSyncMsg.setRet(0);
                    userTableSyncMsg.setActivityId(msg.getActivityId());
                    for(ChefDuelProto.CrossChefDuel2CookerTempMsg cookerMsg : msg.getCookerListList()){
                        ChefDuelProto.ChefDuel2CookerTempMsg.Builder userTempMsg = ChefDuelProto.ChefDuel2CookerTempMsg.newBuilder();
                        userTempMsg.setServerId(cookerMsg.getServerId());
                        userTempMsg.setUserId(cookerMsg.getUserId());
                        if(cookerMsg.getCanEat()){
                            userTempMsg.setCanEat(!cookerMsg.getNoEatUserIdList().contains(chefDuelData.getUserId()));
                        }else{
                            userTempMsg.setCanEat(false);
                        }
                        userTempMsg.setUserInfo(cookerMsg.getUserInfo());
                        userTempMsg.setRank(cookerMsg.getRank());
                        userTempMsg.setActivityId(msg.getActivityId());
                        userTableSyncMsg.addCookerList(userTempMsg);
                    }
                    player.sendPacket(Protocol.U_CHEF_DUEL2_GET_TABLE_USER, userTableSyncMsg);
                }
            }
        }
    }

    //有人加入宴会了增加开宴者每道菜的积分
    private void addHomeDishIntegral(long homeUserId,int tableId,long addValue){
        if(chefDuelDataMap.containsKey(homeUserId)){
            ChefDuelData chefDuelData = chefDuelDataMap.get(homeUserId);
            Map<Integer,ChefDuel2Dish> chefDuel2DishMap = chefDuelData.getFinishDishMap();
            for(ChefDuel2Dish chefDuel2Dish : chefDuel2DishMap.values()){
                if(chefDuel2Dish.getTableId() == tableId){
                    chefDuel2Dish.setIntegral(chefDuel2Dish.getIntegral() + addValue);
                    break;
                }
            }
            chefDuelData.setFinishDishMap(chefDuel2DishMap);
        }
    }

    public void openerBackMsg(long userId,int spoonId,int tableId, int autoJoin){
        Object locker = getLock(userId);
        synchronized (locker){
            ChefDuelData chefDuelData = chefDuelDataMap.get(userId);
            ChefDuel2Spoon chefDuel2Spoon = ChefDuelActivityMgr.getChefDuel2Spoon(activityInfo.getActivityId(),spoonId);
            GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
            chefDuelData.setAllIntegral(chefDuelData.getAllIntegral() + chefDuel2Spoon.getUserIntegral());
            chefDuelData.setRankTime(System.currentTimeMillis());
            addHomeDishIntegral(userId,tableId,chefDuel2Spoon.getUserIntegral());
            if(player != null){
                int integralId = ChefDuelActivityMgr.getChefDuel2IntegralItemId(activityInfo.getActivityId());
                if (autoJoin == 0) { // 主动试
                    String reward = integralId + "=" + chefDuel2Spoon.getUserIntegral();
                    player.getModule(CurrencyModule.class).addCurrency(reward,eLogMoneyType.ChefDuel,eLogMoneyType.CrossChefDuel2JoinBanquetReward);
                }
                player.getModule(ChefDuelModule.class).syncSelfDishTable(activityInfo.getActivityId(),"");
            }else{
                chefDuelData.setIntegral(chefDuelData.getIntegral() + chefDuel2Spoon.getUserIntegral());
            }
            synchronized (needUpdateChefDuelList){
                if(!needUpdateChefDuelList.contains(chefDuelData)){
                    needUpdateChefDuelList.add(chefDuelData);
                }
            }
            UserInfo userInfo = UserMgr.getUserInfo(userId);
            RelationActivityMgr.conditionNotify(activityInfo.getActivityId(),userId, eGamePlayerEventType.ChefDuel2IntegralUserCrossRank.getValue(),
                    new RelationActivityUnionRiseRankArgs(UnionRiseRankArgs.NOTIFY_TYPE_NORMAL, BigInteger.valueOf(chefDuel2Spoon.getUserIntegral()),userInfo.getUnionUid(), activityInfo.getActivityId()));
        }
    }

    public String joinerBackMsg(long userId,int spoonId, int autoJoin){
        Object locker = getLock(userId);
        synchronized (locker){
            ChefDuelData chefDuelData = chefDuelDataMap.get(userId);
            ChefDuel2Spoon chefDuel2Spoon = ChefDuelActivityMgr.getChefDuel2Spoon(activityInfo.getActivityId(),spoonId);
            GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
            int integralId = ChefDuelActivityMgr.getChefDuel2IntegralItemId(activityInfo.getActivityId());
            String reward = "";
            if (autoJoin == 0) { // 主动试吃，访客直接获取奖励
                player.getModule(CurrencyModule.class).removeCurrency(PropertyHelper.parseStringToProperty(chefDuel2Spoon.getConsume()), eLogMoneyType.ChefDuel, eLogMoneyType.CrossChefDuel2JoinBanquetConsume);
                reward = integralId + "=" + chefDuel2Spoon.getJoinerIntegral();
                player.getModule(CurrencyModule.class).addCurrency(reward,eLogMoneyType.ChefDuel,eLogMoneyType.CrossChefDuel2JoinBanquetOwnerReward);
            }
            UserInfo userInfo = UserMgr.getUserInfo(userId);
            RelationActivityMgr.conditionNotify(activityInfo.getActivityId(),userId, eGamePlayerEventType.ChefDuel2IntegralUserCrossRank.getValue(),
                    new RelationActivityUnionRiseRankArgs(UnionRiseRankArgs.NOTIFY_TYPE_NORMAL, BigInteger.valueOf(chefDuel2Spoon.getJoinerIntegral()),userInfo.getUnionUid(), activityInfo.getActivityId()));
            chefDuelData.setAllIntegral(chefDuelData.getAllIntegral() + chefDuel2Spoon.getJoinerIntegral());
            chefDuelData.setRankTime(System.currentTimeMillis());
            GamePlayer playerOpener = GamePlayerMgr.getOnlinePlayer(userId);
            if(playerOpener != null){
                playerOpener.getModule(ChefDuelModule.class).syncSelfDishTable(activityInfo.getActivityId(),"");
            }
            synchronized (needUpdateChefDuelList){
                if(!needUpdateChefDuelList.contains(chefDuelData)){
                    needUpdateChefDuelList.add(chefDuelData);
                }
            }
            return reward;
        }
    }

    //参加宴会
    public void addPromotionUserList(int cook1AcId, List<ChefDuelProto.CrossChefDuelWindUpCookerTempMsg> userIdList, Map<Long,ChefDuelData> windUpUserChefDuel1Map) {
        //加入没有更新，表示本服已经更新成功某个活动的晋级了，通知跨服，跨服不在下达晋级，如果通知晋级的同步没了就重新登录
        if(windUpChefDuel(userIdList)){

        }
        ChefDuelProto.CrossChefDuel2CookerJoinSyncMsg.Builder reqMsg = ChefDuelProto.CrossChefDuel2CookerJoinSyncMsg.newBuilder();
        reqMsg.setActivityId(activityInfo.getActivityId());
        for(ChefDuelProto.CrossChefDuelWindUpCookerTempMsg tempMsg : userIdList){
            ChefDuelProto.CrossChefDuelWindUpCookerTempMsg.Builder userMsg = ChefDuelProto.CrossChefDuelWindUpCookerTempMsg.newBuilder();
            userMsg.setUserId(tempMsg.getUserId());
            userMsg.setScore(0);
            userMsg.setRank(tempMsg.getRank());
            if(windUpUserChefDuel1Map.containsKey(tempMsg.getUserId())) {
                userMsg.setScore(windUpUserChefDuel1Map.get(tempMsg.getUserId()).getAllIntegral());//不知道哪个前面的活动晋级的
            }
            UserBaseInfo userBaseInfo = UserMgr.parseUserBaseInfo(UserMgr.getUserInfo(tempMsg.getUserId()), GameServer.getInstance().getServerId());
            if(userBaseInfo != null){
                userMsg.setPlayerBaseData(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
            }
            reqMsg.addUserInfoList(userMsg);
        }
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_CHEF_DUEL2_COOKER_JOIN, reqMsg);
        GamePlayerMgr.sendPacket(0, pbMsg);
    }

    //参加宴会
    public int sendJoinMsg(long userId,long homeUserId,int tableId,int spoonId, int trueActivityId, int campId){
        ChefDuelProto.ChefDuel2JoinTableReqMsg.Builder reqMsg = ChefDuelProto.ChefDuel2JoinTableReqMsg.newBuilder();
        reqMsg.setActivityId(activityInfo.getActivityId());
        reqMsg.setUserId(homeUserId);
        reqMsg.setTableId(tableId);
        reqMsg.setSpoonId(spoonId);
        reqMsg.setOtherActivityId(trueActivityId);
        reqMsg.setCampId(campId);
        //参加时，统一带上玩家基础信息
        UserInfo infoInRAM = UserMgr.getUserInfoInRAM(userId);
        if(infoInRAM != null){
            reqMsg.setUserBaseInfo(PlayerPb.parsePlayerBaseTempMsg(infoInRAM));
        }
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_CHEF_DUEL2_JOIN_TABLE, reqMsg);
        GamePlayerMgr.sendPacket(userId, pbMsg);
        return 0;
    }

    //预参加宴会
    public int sendPreJoinMsg(long userId,long homeUserId,int tableId,int spoonId, int trueActivityId, int campId){

        //先判断道具是否被禁用
        GamePlayer onlinePlayer = GamePlayerMgr.getOnlinePlayer(userId);
        if(onlinePlayer == null){
            return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
        }

        ChefDuelModule module = onlinePlayer.getModule(ChefDuelModule.class);
        List<Integer> forbidSpoonIdList = module.getForbidSpoonIdList(trueActivityId);
        if(forbidSpoonIdList.contains(spoonId)){
            ChefDuelProto.ChefDuel2PreJoinTableRespMsg.Builder respMsg = ChefDuelProto.ChefDuel2PreJoinTableRespMsg.newBuilder();
            respMsg.addAllForbidSpoonId(module.getForbidSpoonIdList(trueActivityId));
            respMsg.setReason(3);
            respMsg.setRet(0);
            onlinePlayer.sendPacket(Protocol.U_CHEF_DUEL2_PRE_JOIN_TABLE, respMsg);
            return 0;
        }
        //判断我方是否满座
        ChefDuelProto.ChefDuel2PreJoinTableReqMsg.Builder reqMsg = ChefDuelProto.ChefDuel2PreJoinTableReqMsg.newBuilder();
        reqMsg.setActivityId(trueActivityId);
        reqMsg.setUserId(homeUserId);
        reqMsg.setTableId(tableId);
        reqMsg.setSpoonId(spoonId);
        reqMsg.setOtherActivityId(activityInfo.getActivityId());
        reqMsg.setCampId(campId);

        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_CHEF_DUEL2_PRE_JOIN_TABLE, reqMsg);
        GamePlayerMgr.sendPacket(userId, pbMsg);
        return 0;
    }

    public int sendServeDish(long userId,List<Integer> dishIdList){
        ChefDuelData chefDuelData = chefDuelDataMap.get(userId);
        Map<Integer,ChefDuel2Dish> chefDuel2DishMap = chefDuelData.getFinishDishMap();
        for(int id : dishIdList){
            if(!chefDuel2DishMap.containsKey(id)){
                return GameErrorCode.E_CHEF_DUEL2_DISH_NO_FOUND;
            }
            ChefDuel2Dish chefDuel2Dish = chefDuel2DishMap.get(id);
            if(chefDuel2Dish.getStatus() != 0){
                return GameErrorCode.E_CHEF_DUEL2_DISH_IS_SERVE;
            }
        }
        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
        if(player != null){
            ChefDuelProto.CrossChefDuelServeDishReqMsg.Builder reqMsg = ChefDuelProto.CrossChefDuelServeDishReqMsg.newBuilder();
            reqMsg.setActivityId(activityInfo.getActivityId());
            reqMsg.setUserId(userId);
            for(int id : dishIdList){
                ChefDuelProto.CrossChefDuelServeDishInfoMsg.Builder dishMsg = ChefDuelProto.CrossChefDuelServeDishInfoMsg.newBuilder();
                ChefDuel2Dish chefDuel2Dish = chefDuel2DishMap.get(id);
                chefDuel2Dish.setStatus(1);
                dishMsg.setId(id);
                dishMsg.setDishId(chefDuel2Dish.getDishId());
                reqMsg.addDishList(dishMsg);
                //ChefDuel2DishConfig chefDuel2DishConfig = ChefDuelActivityMgr.getDishConfig(activityInfo.getActivityId(),chefDuel2Dish.getDishId());
                //跨服返回再加
                //AutoLogMgr.add(new LogChefDuel2FinishFood(activityInfo.getActivityId(), userId, chefDuel2Dish.getIndex(), chefDuel2Dish.getDishId(), chefDuel2DishConfig.getQuality(), 1));
            }
            chefDuelData.setFinishDishMap(chefDuel2DishMap);
            reqMsg.setPlayerBaseData(PlayerBasePb.parsePlayerBaseTempMsg(UserMgr.parseUserBaseInfo(player.getUserInfo(), GameServer.getInstance().getServerId())));
            YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_CHEF_DUEL2_SERVE_DISH, reqMsg);
            GamePlayerMgr.sendPacket(userId, pbMsg);
            player.getModule(ChefDuelModule.class).syncSelfDishTable(activityInfo.getActivityId(),"");
        }
        synchronized (needUpdateChefDuelList){
            if(!needUpdateChefDuelList.contains(chefDuelData)){
                needUpdateChefDuelList.add(chefDuelData);
            }
        }
        return 0;
    }

    //设置禁止试吃的汤勺类型
    public int sendForbidSpoon(long userId,List<Integer> spoonIdList){
        for(Integer spoonId : spoonIdList){
            ChefDuel2Spoon spoon = ChefDuelActivityMgr.getChefDuel2Spoon(activityInfo.getActivityId(),spoonId);
            if(spoon == null){
                return GameErrorCode.E_CHEF_DUEL2_SPOON_NOT_FOUND;
            }
        }
        ChefDuelProto.ChefDuel2ForbidSpoonReqMsg.Builder reqMsg = ChefDuelProto.ChefDuel2ForbidSpoonReqMsg.newBuilder();
        reqMsg.setActivityId(getActivityInfo().getActivityId());
        reqMsg.addAllSpoonId(spoonIdList);
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_CHEF_DUEL2_FROBID_SPOON, reqMsg);
        GamePlayerMgr.sendPacket(userId, pbMsg);
        return 0;
    }

    public int sendCookerHomeMsg(long userId,long homeUserId,int page,int num){
        //请求的时候要加上是不是进去场景的
        ChefDuelProto.CrossChefDuel2CookerHomeReqMsg.Builder reqMsg = ChefDuelProto.CrossChefDuel2CookerHomeReqMsg.newBuilder();
        reqMsg.setActivityId(activityInfo.getActivityId());
        reqMsg.setUserId(homeUserId);
        reqMsg.setPage(page);
        reqMsg.setNum(num);
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_CHEF_DUEL2_COOKER_HOME, reqMsg);
        GamePlayerMgr.sendPacket(userId, pbMsg);
        return 0;
    }

    public int sendCookerTableMsg(long userId,long homeUserId,int tableId){
        //请求的时候要加上是不是进去场景的
        ChefDuelProto.CrossChefDuel2CookerTableReqMsg.Builder reqMsg = ChefDuelProto.CrossChefDuel2CookerTableReqMsg.newBuilder();
        reqMsg.setActivityId(activityInfo.getActivityId());
        reqMsg.setUserId(homeUserId);
        reqMsg.setTableId(tableId);
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_CHEF_DUEL2_USER_TABLE_INFO, reqMsg);
        GamePlayerMgr.sendPacket(userId, pbMsg);
        return 0;
    }

    public int sendCookerMsg(long userId){
        //请求的时候要加上是不是进去场景的
        ChefDuelProto.CrossChefDuel2CookerReqMsg.Builder reqMsg = ChefDuelProto.CrossChefDuel2CookerReqMsg.newBuilder();
        reqMsg.setActivityId(activityInfo.getActivityId());
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_CHEF_DUEL2_COOKER_REQ, reqMsg);
        GamePlayerMgr.sendPacket(userId, pbMsg);
        return 0;
    }

    public int sendRewardMsg(long userId){
        //请求的时候要加上是不是进去场景的
        ChefDuelProto.CrossChefDuel2GetRecordMsg.Builder reqMsg = ChefDuelProto.CrossChefDuel2GetRecordMsg.newBuilder();
        reqMsg.setActivityId(activityInfo.getActivityId());
        reqMsg.setUserId(userId);
//		reqMsg.setServerId(RelativesMgr.getUserServerId(userId));
        reqMsg.setServerId(0L);
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_CHEF_DUEL2_RECORD, reqMsg);
        GamePlayerMgr.sendPacket(userId, pbMsg);
        return 0;
    }

    private boolean isAbleJoinChefDuel(long userId){
        if(chefDuelDataMap.containsKey(userId)){
            return chefDuelDataMap.get(userId).isAble();
        }
        return false;
    }

    public int sendRelationMsg(long userId){
        //请求的时候要加上是不是进去场景的
        ChefDuelProto.CrossChefDuel2SearchReqMsg.Builder reqMsg = ChefDuelProto.CrossChefDuel2SearchReqMsg.newBuilder();
        reqMsg.setActivityId(activityInfo.getActivityId());
        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
        Map<Long, CrossUnionMember> unionMemberMap = CrossUnionMgr.getUnionMemberMap(player.getUserInfo().getUnionUid());
        if(unionMemberMap != null){
            for(UnionMember unionMember : unionMemberMap.values()){
                if(unionMember.getUserId() != userId){
                    reqMsg.addUnionList(unionMember.getUserId());
                }
            }
        }
        Map<Long, RelativesInfo> relativesMap = player.getModule(RelativesModule.class).getRelativesMap();
        for(Long reUserId : relativesMap.keySet()){
            if(relativesMap.get(reUserId).getStatus() == 1){
                reqMsg.addMarryList(reUserId);
            }
        }
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_CHEF_DUEL2_UNION_RELATION, reqMsg);
        GamePlayerMgr.sendPacket(userId, pbMsg);
        return 0;
    }
    public int sendCanEastSearchMsg(long userId){
        //请求的时候要加上是不是进去场景的
        ChefDuelProto.ChefDuel2SearchAllReqMsg.Builder reqMsg = ChefDuelProto.ChefDuel2SearchAllReqMsg.newBuilder();
        reqMsg.setActivityId(activityInfo.getActivityId());
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_CHEF_DUEL2_SEARCH_ALL, reqMsg);
        GamePlayerMgr.sendPacket(userId, pbMsg);

        //同时拉取赴宴范围的全部玩家
        for (Map.Entry<Integer, OtherActivityChefDuel2> entry : OtherActivityChefDuelActivityMgr.getChefDuel2Map().entrySet()) {
            if(ActivityMgr.activityInTime(entry.getValue().getActivityInfo())){
                ChefDuelProto.CrossChefDuel2SearchReqMsg.Builder otherMsg = ChefDuelProto.CrossChefDuel2SearchReqMsg.newBuilder();
                otherMsg.setActivityId(entry.getKey());
                YanQuMessage otherPbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_CHEF_DUEL2_SEARCH_ALL, otherMsg);
                GamePlayerMgr.sendPacket(userId, otherPbMsg);
            }
        }

        return 0;
    }

    public int sendSearchUserMsg(long userId,String searchId){
        //请求的时候要加上是不是进去场景的
        ChefDuelProto.ChefDuel2SearchOneReqMsg.Builder reqMsg = ChefDuelProto.ChefDuel2SearchOneReqMsg.newBuilder();
        reqMsg.setActivityId(activityInfo.getActivityId());
        reqMsg.setSearchId(searchId);
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_CHEF_DUEL2_SEARCH_USER, reqMsg);
        GamePlayerMgr.sendPacket(userId, pbMsg);
        return 0;
    }

    public ChefDuelData getUserChefDuelData(GamePlayer player){
        //领奖期或者重新登录了清掉道具
        if(!chefDuelDataMap.containsKey(player.getUserId())){
//			clearIntegral(player,ChefDuelActivityMgr.getChefDuel2IntegralItemId(activityInfo.getActivityId()));
            //不回收了，改成领奖期间才回收
//			clearPickUpItem(player,ChefDuelActivityMgr.getChefDuel2PickUpItemId(activityInfo.getActivityId()));
            chefDuelDataMap.put(player.getUserId(),initChefDuel2(player.getUserId()));
        }else{
            reAddIntegral(player,ChefDuelActivityMgr.getChefDuel2IntegralItemId(activityInfo.getActivityId()));
        }
        return chefDuelDataMap.get(player.getUserId());
    }

    //重新加积分
    public void reAddIntegral(GamePlayer player,int itemId){
        Object locker = getLock(player.getUserId());
        synchronized (locker){
            int integralItemId = ChefDuelActivityMgr.getChefDuel2IntegralItemId(activityInfo.getActivityId());
            if(itemId == integralItemId){
                ChefDuelData chefDuelData = chefDuelDataMap.get(player.getUserId());
                if(chefDuelData.getIntegral() > 0){
                    player.getModule(CurrencyModule.class).addCurrency(integralItemId + "=" + chefDuelData.getIntegral(), eLogMoneyType.ChefDuel,eLogMoneyType.CrossChefDuel2ActivityLogin);
                    chefDuelData.setIntegral(0);
                    synchronized (needUpdateChefDuelList){
                        if(!needUpdateChefDuelList.contains(chefDuelData)){
                            needUpdateChefDuelList.add(chefDuelData);
                        }
                    }
                }
            }
        }
    }

    public void clearIntegral(GamePlayer player,int itemId){
        Object locker = getLock(player.getUserId());
        synchronized (locker){
            int integralItemId = ChefDuelActivityMgr.getChefDuel2IntegralItemId(activityInfo.getActivityId());
            if(itemId == integralItemId){
                UserBagItem userBagItem = player.getModule(BagModule.class).getUserBagItem(integralItemId);
                if(userBagItem != null){
                    player.getModule(CurrencyModule.class).removeCurrency(PropertyHelper.parseStringToProperty(integralItemId + "=" + userBagItem.getNum()), eLogMoneyType.ChefDuel,eLogMoneyType.CrossChefDuel2ActivityNewAc);
                }
            }
        }
    }

    public void clearPickUpItem(GamePlayer player,int itemId){
        Object locker = getLock(player.getUserId());
        synchronized (locker){
            int pickUpItemId = ChefDuelActivityMgr.getChefDuel2PickUpItemId(activityInfo.getActivityId());
            int integralItemId = ChefDuelActivityMgr.getChefDuel2IntegralItemId(activityInfo.getActivityId());
            if(itemId == pickUpItemId){
                UserBagItem userBagPickUpItem = player.getModule(BagModule.class).getUserBagItem(pickUpItemId);
                GoodsInfo goodsInfo = GoodsMgr.getGoodsById(itemId);
                if(userBagPickUpItem != null){
                    player.getModule(CurrencyModule.class).removeCurrency(PropertyHelper.parseStringToProperty(pickUpItemId + "=" + userBagPickUpItem.getNum()), eLogMoneyType.ChefDuel,eLogMoneyType.CrossChefDuel2ActivityNewAc);
                    player.getModule(CurrencyModule.class).addCurrency(PropertyHelper.parseStringToProperty(integralItemId + "=" + BigInteger.valueOf(userBagPickUpItem.getNum()).multiply(goodsInfo.getParamList().get(1)).toString()), eLogMoneyType.ChefDuel,eLogMoneyType.CrossChefDuel2ActivityNewAc);
                }
            }
        }
    }

    public PickDishRes pickDish(long userId, int times){
        PickDishRes res = new PickDishRes();
        ChefDuelData chefDuelData = chefDuelDataMap.get(userId);
        if(!chefDuelData.isAble() || chefDuelData.getNo() != eChefDuelActivityType.Phase2.getChildType()){
            res.setRet(GameErrorCode.E_ACTIVITY_NO_FOUND);
            return res;
        }
        recoveryPickDishHp(chefDuelData);
        if(chefDuelData.getHp() - times < 0){
            res.setRet(GameErrorCode.E_CHEF_DUEL_MAKE_FOOD_NO_HP);
            return res;
        }

        //次数大于剩余的空位置是修正到满
        int emptyCount = 4 - chefDuelData.getProcess();
        if(times > emptyCount){
            times = emptyCount;
        }
        if(chefDuelData.getDishId() == 0){
            ChefDuel2DishConfig chefDuel2DishConfig = ChefDuelActivityMgr.randomPickDishId(activityInfo.getActivityId());
            chefDuelData.setDishId(chefDuel2DishConfig.getId());
        }
        chefDuelData.setHp(chefDuelData.getHp() - times);
        chefDuelData.setProcess(chefDuelData.getProcess() + times);
        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
        //每次挑菜的随机奖励
        List<String> randomRewardList = new ArrayList<>();
        if(times > 0){
            randomRewardList = ChefDuelActivityMgr.randomPickReward(activityInfo.getActivityId(), times);
        }

        if(player != null){
            player.getModule(ChefDuelModule.class).syncSelfDishTable(activityInfo.getActivityId(), StringUtils.listToString(randomRewardList,"|"));
        }

        synchronized (needUpdateChefDuelList){
            if(!needUpdateChefDuelList.contains(chefDuelData)){
                needUpdateChefDuelList.add(chefDuelData);
            }
        }
        return res;
    }

    public PickDishRes newPickDish(long userId,int times){
        PickDishRes res = new PickDishRes();
        ChefDuelData chefDuelData = chefDuelDataMap.get(userId);
        if(!chefDuelData.isAble() || chefDuelData.getNo() != eChefDuelActivityType.Phase2.getChildType()){
            res.setRet(GameErrorCode.E_ACTIVITY_NO_FOUND);
            return res;
        }
        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
        if(player == null){
            res.setRet(GameErrorCode.E_USER_NO_FOUND);
            return res;
        }
        //次数大于剩余的空位置是修正到满
        int emptyCount = 4 - chefDuelData.getProcess();
        if(times > emptyCount){
            times = emptyCount;
        }
        //扣体力变成扣道具
        int pickUpItemId = ChefDuelActivityMgr.getChefDuel2PickUpItemId(activityInfo.getActivityId());
        Property consume =  PropertyHelper.parseStringToProperty(pickUpItemId + "=" + times);
        if(!player.getModule(CurrencyModule.class).currencyIsEnough(consume)){
            res.setRet(GameErrorCode.E_BAG_ITEM_NO_ENOUGH);
            return res;
        }
        player.getModule(CurrencyModule.class).removeCurrency(consume,eLogMoneyType.ChefDuel,eLogMoneyType.CrossChefDuel2PickUpConsume);

        if(chefDuelData.getDishId() == 0){
            ChefDuel2DishConfig chefDuel2DishConfig = ChefDuelActivityMgr.randomPickDishId(activityInfo.getActivityId());
            chefDuelData.setDishId(chefDuel2DishConfig.getId());
        }

        chefDuelData.setProcess(chefDuelData.getProcess() + times);
        //每次挑菜的随机奖励
        List<String> randomRewardList = new ArrayList<>();
        if(times > 0){
            randomRewardList = ChefDuelActivityMgr.randomPickReward(activityInfo.getActivityId(),times);
        }
        Property propertyReward = new Property();
        for(String reward : randomRewardList){
            propertyReward.addProperty(PropertyHelper.parseStringToProperty(reward));
        }
        player.getModule(CurrencyModule.class).addCurrency(propertyReward,eLogMoneyType.ChefDuel,eLogMoneyType.CrossChefDuel2PickUpReward);
        player.getModule(ChefDuelModule.class).syncSelfDishTable(activityInfo.getActivityId(), StringUtils.listToString(randomRewardList,"|"));
        synchronized (needUpdateChefDuelList){
            if(!needUpdateChefDuelList.contains(chefDuelData)){
                needUpdateChefDuelList.add(chefDuelData);
            }
        }
        AutoLogMgr.add(new LogChefDuel2PickFood(activityInfo.getActivityId(), userId, chefDuelData.getDishId(), times, StringUtils.listToString(randomRewardList, ";"), chefDuelData.getProcess() == 4 ? 1 : 0, chefDuelData.getCampId()));
        return res;
    }

    //使用体力同步体力的时候
    public void recoveryPickDishHp(ChefDuelData chefDuelData){
        int recoveryTime = ChefDuelActivityMgr.getChefDuel2RecoveryTime(chefDuelData.getActivityId());
        int maxHp = ChefDuelActivityMgr.getChefDuel2MaxHp(chefDuelData.getActivityId());
        int hp = chefDuelData.getHp();
        long hpTime = chefDuelData.getHpTime();
        long passTime = System.currentTimeMillis() - hpTime;
        long recoveryValue = passTime/(recoveryTime*1000);
        if(hp + recoveryValue < maxHp){
            chefDuelData.setHp(hp + (int)recoveryValue);
        }else if(hp + recoveryValue >= maxHp){
            chefDuelData.setHp(maxHp);
        }
        chefDuelData.setHpTime(hpTime + recoveryValue * recoveryTime * 1000);
        synchronized (needUpdateChefDuelList){
            if(!needUpdateChefDuelList.contains(chefDuelData)){
                needUpdateChefDuelList.add(chefDuelData);
            }
        }
    }

    //合成最总成品菜
    public List<ChefDuel2Dish> dishMerge(long userId){
        List<ChefDuel2Dish> list = new ArrayList<>();
        Object locker = getLock(userId);
        synchronized (locker){
            ChefDuelData chefDuelData = chefDuelDataMap.get(userId);
            if(chefDuelData == null){
                return null;
            }
            //还没合4下
            if(chefDuelData.getProcess() != 4){
                return null;
            }

            int dishId = chefDuelData.getDishId();


            ChefDuel2Config chefDuel2Config = ChefDuelActivityMgr.getChefDuel2Config(activityInfo.getActivityId());

            if(ChefDuelActivityMgr.isHorseNoticeQuality(activityInfo.getActivityId(), dishId)){
                //跑马灯
                ChefDuelProto.CrossChefDuel2HorseNoticeMsg.Builder reqMsg = ChefDuelProto.CrossChefDuel2HorseNoticeMsg.newBuilder();
                reqMsg.setActivityId(activityInfo.getActivityId());
                reqMsg.setUserId(userId);
                reqMsg.setDishId(dishId);
                reqMsg.setTime(System.currentTimeMillis());
                UserInfo userInfo = UserMgr.getUserInfo(userId);
                UserBaseInfo userBaseInfo = UserMgr.parseUserBaseInfo(userInfo, GameServer.getInstance().getServerId());
                if(userBaseInfo != null){
                    reqMsg.setPlayerBaseData(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
                }
                YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_CHEF_DUEL2_HORSE_RACE_LAMP, reqMsg);
                GamePlayerMgr.sendPacket(userId, pbMsg);
            }

            ChefDuel2DishConfig chefDuel2DishConfig = ChefDuelActivityMgr.getDishConfig(activityInfo.getActivityId(), dishId);
            if(chefDuel2DishConfig == null){
                return null;
            }

            Map<Integer,ChefDuel2Dish> dishMap = chefDuelData.getFinishDishMap();

            long totalAddScore = 0;
            int dishNum = 1;
            if(chefDuelData.getCampId() == 2 && random.nextInt(1000) < chefDuel2Config.getCHEFDUEL2_TEAM2_PARAM()){
                dishNum = 2;
            }
            ChefDuel2Dish newChefDuel2Dish = null;
            for (int i = 0; i < dishNum; i++) {
                newChefDuel2Dish = new ChefDuel2Dish();
                newChefDuel2Dish.setDishId(dishId);
                chefDuelData.setDishId(0);
                chefDuelData.setProcess(0);
                newChefDuel2Dish.setIndex(dishMap.size()+1);
                newChefDuel2Dish.setStatus(0);
                newChefDuel2Dish.setTime(System.currentTimeMillis());
                newChefDuel2Dish.setIntegral(0);
                newChefDuel2Dish.setTableId(0);

                int add = 0;
                //如果角色1，额外加积分
                if(chefDuelData.getCampId() == 1){
                    add = BigDecimal.valueOf(chefDuel2DishConfig.getScore()).multiply(BigDecimal.valueOf(chefDuel2Config.getCHEFDUEL2_TEAM1_PARAM())).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_UP).intValue();
                }
                newChefDuel2Dish.setMakeIntegral(chefDuel2DishConfig.getScore());
                newChefDuel2Dish.setMakeAddition(add);
                dishMap.put(dishMap.size() + 1, newChefDuel2Dish);
                chefDuelData.setAllIntegral(chefDuelData.getAllIntegral() + chefDuel2DishConfig.getScore() + add);
                chefDuelData.setRankTime(System.currentTimeMillis());
                totalAddScore += chefDuel2DishConfig.getScore() + add;
                AutoLogMgr.add(new LogChefDuel2FinishFood(
                        activityInfo.getActivityId(),
                        userId,
                        newChefDuel2Dish.getIndex(),
                        newChefDuel2Dish.getDishId(),
                        chefDuel2DishConfig.getQuality(),
                        1,
                        chefDuelData.getCampId(),
                        chefDuel2DishConfig.getScore() + add,
                        (dishNum == 2 || add > 0) ? 1 : 0));
                list.add(newChefDuel2Dish);
            }

            if(dishNum == 2){
                chefDuelData.setBuffNum(chefDuelData.getBuffNum() + 1);
            }
            chefDuelData.setFinishDishMap(dishMap);

            RelationActivityMgr.conditionNotify(activityInfo.getActivityId(),userId, eGamePlayerEventType.ChefDuel2MakeDishCount.getValue(),dishMap.size());
            RelationActivityMgr.conditionNotify(activityInfo.getActivityId(),userId, eGamePlayerEventType.ChefDuel2MakeDishUnLock.getValue(), newChefDuel2Dish);
            UserInfo userInfo = UserMgr.getUserInfo(userId);

            RelationActivityMgr.conditionNotify(activityInfo.getActivityId(),userId, eGamePlayerEventType.ChefDuel2IntegralUserCrossRank.getValue(),
                    new RelationActivityUnionRiseRankArgs(UnionRiseRankArgs.NOTIFY_TYPE_NORMAL, BigInteger.valueOf(totalAddScore),userInfo.getUnionUid(), activityInfo.getActivityId()));
            GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
            if(player != null){
                int integralId = ChefDuelActivityMgr.getChefDuel2IntegralItemId(activityInfo.getActivityId());
                String reward = integralId + "=" + totalAddScore;
                player.getModule(CurrencyModule.class).addCurrency(reward,eLogMoneyType.ChefDuel,eLogMoneyType.CrossChefDuel2JoinBanquetOwnerReward);
                player.getModule(ChefDuelModule.class).syncSelfDishTable(activityInfo.getActivityId(),"");
            }else{
                chefDuelData.setIntegral(chefDuelData.getIntegral() + totalAddScore);
            }

            synchronized (needUpdateChefDuelList){
                if(!needUpdateChefDuelList.contains(chefDuelData)){
                    needUpdateChefDuelList.add(chefDuelData);
                }
            }
        }
        return list;
    }

    private ChefDuelData initChefDuel2(long userId){
        ChefDuelData temp = new ChefDuelData();
        temp.setActivityId(activityInfo.getActivityId());
        temp.setUserId(userId);
        temp.setNo(activityInfo.getChildType());
        temp.setAble(ChefDuelActivityMgr.isChefDuel2Able(activityInfo.getActivityId()));
        temp.setIntegral(0);
        temp.setAllIntegral(0);
        temp.setRankTime(System.currentTimeMillis());
        temp.setHp(ChefDuelActivityMgr.getChefDuel2Hp(activityInfo.getActivityId()));
        temp.setHpTime(System.currentTimeMillis());
        temp.setFinishFoodId(0);
        temp.setTableFoodData("{}");
        temp.setFinishFoodCount(0);
        temp.setFinishFoodData("{}");
        temp.setDishId(0);
        temp.setProcess(0);
        temp.setDishCount(0);
        synchronized (needAddChefDuelList){
            if(!needAddChefDuelList.contains(temp)){
                needAddChefDuelList.add(temp);
            }
        }
        return temp;
    }

    //活动结算了没上的菜转换成活动兑换积分
    private void dishRecovery(){
        if(ActivityMgr.activityInRewardPeriod(activityInfo) && !acOverRecovery){
            for(Long userId : chefDuelDataMap.keySet()){
                long addAllIntegral = 0;
                ChefDuelData chefDuelData = chefDuelDataMap.get(userId);
                Map<Integer,ChefDuel2Dish> finshDishMap = chefDuelData.getFinishDishMap();
                int dishCount = 0;
                int seatCount = 0;
                for(ChefDuel2Dish chefDuel2Dish : finshDishMap.values()){
                    if(chefDuel2Dish.getStatus() == 3)return;//有结算过的就是跑过了
                    if(chefDuel2Dish.getStatus() == 0){
                        ChefDuel2DishConfig chefDuel2DishConfig = ChefDuelActivityMgr.getDishConfig(activityInfo.getActivityId(),chefDuel2Dish.getDishId());
                        ChefDuel2Spoon chefDuel2Spoon = ChefDuelActivityMgr.getChefDuel2MinSpoon(activityInfo.getActivityId());
                        long recoveryIntegral = chefDuel2DishConfig.getSeat() * chefDuel2Spoon.getUserIntegral();
                        addAllIntegral += recoveryIntegral;
                        chefDuel2Dish.setStatus(3);
                        dishCount++;
                        seatCount = seatCount + chefDuel2DishConfig.getSeat();
                    }
                }
                if(addAllIntegral > 0){
                    chefDuelData.setFinishDishMap(finshDishMap);
                    int integralItemId = ChefDuelActivityMgr.getChefDuel2IntegralItemId(activityInfo.getActivityId());
                    UserInfo userInfo = UserMgr.getUserInfo(userId);
                    String mailTitle = MultipleLanguageMgr.getContent(MailManager.CHEF_DUEL2_FOOD_RECOVERY_TITLE, userInfo.getLanguage());
                    String mailContent = StringUtils.format(MultipleLanguageMgr.getContent(MailManager.CHEF_DUEL2_FOOD_RECOVERY_CONTENT, userInfo.getLanguage()),
                            dishCount,seatCount,addAllIntegral);
                    MailManager.sendMail(userId, eMailType.SYSTEM.getValue(), integralItemId + "=" + addAllIntegral, mailContent, mailTitle);
					/*GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
					if(player != null){
						player.getModule(CurrencyModule.class).addCurrency(integralItemId + "=" + addAllIntegral,eLogMoneyType.ChefDuel,eLogMoneyType.CrossChefDuel2RecoverDish);
					}else{
						//不在线就放着了，登录了放进他的背包，登录的时候查过期活动这个人是否有未领取的直接load库
						chefDuelData.setIntegral(chefDuelData.getIntegral() + addAllIntegral);
					}*/
                    synchronized (needUpdateChefDuelList){
                        if(!needUpdateChefDuelList.contains(chefDuelData)){
                            needUpdateChefDuelList.add(chefDuelData);
                        }
                    }
                }

            }
            acOverRecovery = true;
        }
    }

    public void timerTask(){
        dishRecovery();
        long now = System.currentTimeMillis();
        if (now - lastChekDishStatusTime > 60 * 1000L) {
            lastChekDishStatusTime = now;
            checkServerDishStatus();
        }
    }

    public boolean stop() {
        return false;
    }

    public boolean save() {
        List<ChefDuelData> tempAddList;
        synchronized (needAddChefDuelList) {
            tempAddList = new ArrayList<>(needAddChefDuelList);
            needAddChefDuelList.clear();
        }
        if (tempAddList.size() > 0) {
            new UserChefDuelDaoImpl().addUserCooBoyList(tempAddList);
        }
        //保存记录
        List<ChefDuelData> tempUpdataList;
        synchronized (needUpdateChefDuelList) {
            tempUpdataList = new ArrayList<>(needUpdateChefDuelList);
            needUpdateChefDuelList.clear();
        }
        if (tempUpdataList.size() > 0) {
            new UserChefDuelDaoImpl().updateUserCooBoyList(tempUpdataList);
        }

        for (ChefDuel2AutoJoinSpoon spoon : autoJoinSpoonMap.values()) {
            if (spoon.isUpdateOption()) {
                new UserCommonActivityDataDaoImpl<ChefDuel2AutoJoinSpoon>().update(spoon);
            } else if (spoon.isInsertOption()) {
                new UserCommonActivityDataDaoImpl<ChefDuel2AutoJoinSpoon>().add(spoon);
            }
        }
        return true;
    }

    public boolean reload() {
        chefDuelDataMap = new UserChefDuelDaoImpl().getUserChefDuelMap(activityInfo.getActivityId());
        autoJoinSpoonMap = new UserCommonActivityDataDaoImpl<ChefDuel2AutoJoinSpoon>().getActivityUserData(ChefDuel2AutoJoinSpoon.class, activityInfo.getActivityId());
        return true;
    }

    public boolean isUserChefDuel2Able(long userId) {
        if(chefDuelDataMap.containsKey(userId)){
            return chefDuelDataMap.get(userId).isAble();
        }
        return false;
    }

    public void checkServerDishStatus() {
        Map<Long, List<ChefDuel2Dish>> needCheckMap = new HashMap<>();
        for (ChefDuelData chefDuelData : new ArrayList<>(chefDuelDataMap.values())) {
            List<ChefDuel2Dish> servingDishList = new ArrayList<>();
            Map<Integer, ChefDuel2Dish> finishDishMap = chefDuelData.getFinishDishMap();
            for (ChefDuel2Dish dish : new ArrayList<>(finishDishMap.values())) {
                if (dish.getStatus() == 1) {
                    servingDishList.add(dish);
                }
            }
            if (servingDishList.isEmpty()) {
                continue;
            }
            needCheckMap.put(chefDuelData.getUserId(), servingDishList);
        }
        if (needCheckMap.isEmpty()) {
            return;
        }
        ChefDuelProto.CheckChefDuel2DishStatusMsg.Builder reqMsg = ChefDuelProto.CheckChefDuel2DishStatusMsg.newBuilder();
        reqMsg.setActivityId(activityInfo.getActivityId());
        for (Map.Entry<Long, List<ChefDuel2Dish>> entry : needCheckMap.entrySet()) {
            Long userId = entry.getKey();
            List<ChefDuel2Dish> dishList = entry.getValue();
            for (ChefDuel2Dish dish : dishList) {
                ChefDuelProto.NeedCheckChefDuel2DishMsg.Builder msg = ChefDuelProto.NeedCheckChefDuel2DishMsg.newBuilder();
                msg.setUserId(userId);
                msg.setDishId(dish.getTableId());
                reqMsg.addDish(msg);
            }
        }
        YanQuMessage message = YanQuMessageUtils.buildMessage(CrossProtocol.C_CROSS_CHEF_DUEL2_CHECK_FOOD_STATUS, reqMsg);
        GamePlayerMgr.sendPacket(0, message);
    }

    public void selectCamp(long playerId, int campId) {
        ChefDuelData chefDuelData = chefDuelDataMap.get(playerId);
        if(chefDuelData != null){
            chefDuelData.setCampId(campId);
            synchronized (needUpdateChefDuelList){
                if(!needUpdateChefDuelList.contains(chefDuelData)){
                    needUpdateChefDuelList.add(chefDuelData);
                }
            }
        }
        YanQuMessage message = YanQuMessageUtils.buildMessage(Protocol.U_CHEF_DUEL2_SELECT_CAMP, ChefDuelProto.ChefDuel2CampSelectRespMsg.newBuilder().setRet(0).setCampId(campId));
        GamePlayerMgr.sendPacket(playerId, message);
    }


    public void checkUpUserScoreUpload() {
        long lastUploadTime = System.currentTimeMillis();
        ChefDuelProto.CrossChefDuel2ScoreUploadMsg.Builder msg = ChefDuelProto.CrossChefDuel2ScoreUploadMsg.newBuilder();
        msg.setActivityId(activityInfo.getActivityId());
        for (Map.Entry<Long, ChefDuelData> entry : chefDuelDataMap.entrySet()) {
            if(entry.getValue().getRankTime() >= this.lastUploadTime){
                ChefDuelProto.CrossChefDuel2ScoreTemp.Builder temp = ChefDuelProto.CrossChefDuel2ScoreTemp.newBuilder();
                temp.setUserId(entry.getKey());
                temp.setScore(entry.getValue().getAllIntegral());
                temp.setTime(entry.getValue().getRankTime());
                msg.addScore(temp);
            }
        }
        this.lastUploadTime = lastUploadTime;

        if(msg.getScoreCount() > 0){
            GamePlayerMgr.sendPacket(0, YanQuMessageUtils.buildMessage(Protocol.C_CROSS_CHEF_DUEL2_SCORE_UPLOAD, msg));
        }
    }
    
    //自动回宴 =========================================================
    /**
     * 获取自动回访汤勺
     *
     * @param userId 用户ID
     * @return ret
     */
    public int getAutoJoinRecord(long userId) {
        ChefDuelProto.CrossChefDuel2GetAutoJoinRecordMsg.Builder reqMsg =
                ChefDuelProto.CrossChefDuel2GetAutoJoinRecordMsg.newBuilder();

        reqMsg.setActivityId(activityInfo.getActivityId());
        reqMsg.setUserId(userId);
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_CHEF_DUEL2_GET_AUTO_JOIN_RECORD, reqMsg);
        GamePlayerMgr.sendPacket(userId, pbMsg);

        return 0;
    }

    /**
     * 设置自动回访汤勺
     *
     * @param activityId 活动ID
     * @param userId     用户ID
     * @param spoons     汤勺
     * @return ret
     */
    public int setAutoJoinSpoon(int activityId, long userId, List<ChefDuelProto.ChefDuel2SpoonTempMsg> spoons) {
        ChefDuelProto.ChefDuel2SetAutoJoinSpoonRespMsg.Builder respMsg =
                ChefDuelProto.ChefDuel2SetAutoJoinSpoonRespMsg.newBuilder();
        respMsg.setRet(0);
        if (!autoJoinSpoonMap.containsKey(userId)) {
            respMsg.setRet(GameErrorCode.E_CHEF_DUEL2_GET_AUTO_JOIN_SPOON_FAIL);
            return GameErrorCode.E_CHEF_DUEL2_GET_AUTO_JOIN_SPOON_FAIL;
        }

        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);

        Property deducts = new Property();
        Property returns = new Property();
        Object locker = getLock(userId);
        synchronized (locker) {
            ChefDuel2AutoJoinSpoon autoJoinSpoon = autoJoinSpoonMap.get(userId);
            ConcurrentHashMap<Integer, Integer> spoonMap = autoJoinSpoon.getSpoonMap();
            ConcurrentHashMap<Integer, Integer> tmpSpoonMap = new ConcurrentHashMap<>(spoonMap);
            List<Integer> confSpoonIds = ChefDuelActivityMgr.getChefDuel2SpoonIdList(activityId);
            for (ChefDuelProto.ChefDuel2SpoonTempMsg spoon : spoons) {
                int spoonId = spoon.getId();
                int oriSpoonCnt = spoonMap.get(spoonId);
                int diff = spoon.getCnt();
                if (!confSpoonIds.contains(spoonId)) { // 汤勺ID不存在
                    return GameErrorCode.E_CHEF_DUEL2_SPOON_NOT_FOUND;
                }
                if (diff > 0) {
                    deducts.addProperty(spoonId, diff);
                } else if (diff < 0) { // 取消或减少自动回访汤勺数量的设置，将差额用邮件发送
                    if (oriSpoonCnt < Math.abs(diff)) { // 现有的值不够减，别扣到0，直接设置错误码
                        return GameErrorCode.E_CHEF_DUEL2_AUTO_JOIN_SPOON_NOT_ENOUGH;
                    }
                    returns.addProperty(spoonId, Math.abs(diff));
                }
                tmpSpoonMap.merge(spoonId, diff, Integer::sum);
            }
            autoJoinSpoon.setSpoonMap(tmpSpoonMap);
        }

        if (!returns.isNothing()) { // 处理取消设置返还的汤勺
            UserInfo userInfo = UserMgr.getUserInfo(userId);
            String language = LanguageType.LANGUAGE_DEFAULT;
            if (null != userInfo) {
                language = userInfo.getLanguage();
            }
            String title = MultipleLanguageMgr.getContent(MailManager.CHEFDUEL_BANQUET_MAIL_TITLE_2, language);
            String content = MultipleLanguageMgr.getContent(MailManager.CHEFDUEL_BANQUET_MAIL_CONTENT_2, language);
            MailManager.sendMail(userId, eMailType.SYSTEM.getValue(), returns.toHelperString(), content, title);
        }

        if (!deducts.isNothing()) { // 实际扣除新增的回访道具
            if (!player.getModule(CurrencyModule.class).removeCurrency(deducts, eLogMoneyType.ChefDuel,
                    eLogMoneyType.CrossChefDuel2AutoJoinDeduct)) {
                return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
            }
        }

        ChefDuelProto.CrossChefDuel2SyncAutoJoinSpoonMsg.Builder reqMsg = ChefDuelProto.CrossChefDuel2SyncAutoJoinSpoonMsg.newBuilder();
        if (autoJoinSpoonMap.containsKey(userId)) {
            ChefDuel2AutoJoinSpoon autoJoinSpoon = autoJoinSpoonMap.get(userId);
            for (Map.Entry<Integer, Integer> kv : autoJoinSpoon.getSpoonMap().entrySet()) {
                ChefDuelProto.ChefDuel2SpoonTempMsg.Builder spoonTemp =
                        ChefDuelProto.ChefDuel2SpoonTempMsg.newBuilder();
                spoonTemp.setId(kv.getKey());
                spoonTemp.setCnt(kv.getValue());
                respMsg.addSpoon(spoonTemp);
                reqMsg.addSpoon(spoonTemp);
            }
        }
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.U_CHEF_DUEL2_SET_AUTO_JOIN_SPOON, respMsg);
        GamePlayerMgr.sendPacket(userId, pbMsg);

        reqMsg.setActivityId(activityId);
        reqMsg.setUserId(userId);
        YanQuMessage pbMsg1 = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_CHEF_DUEL2_SYNC_AUTO_JOIN_SPOON, reqMsg);
        GamePlayerMgr.sendPacket(userId, pbMsg1);

        return 0;
    }

    /**
     * 获取自动回访记录
     *
     * @param activityId 活动ID
     * @param userId     用户ID
     * @return ret
     */
    public int getAutoJoinSpoon(int activityId, long userId) {
        ChefDuelProto.ChefDuel2GetAutoJoinSpoonRespMsg.Builder respMsg =
                ChefDuelProto.ChefDuel2GetAutoJoinSpoonRespMsg.newBuilder();

        respMsg.setRet(0);
        List<Integer> spoonIds = ChefDuelActivityMgr.getChefDuel2SpoonIdList(activityId);
        if (!autoJoinSpoonMap.containsKey(userId)) { // 没有记录时初始化
            ChefDuel2AutoJoinSpoon tmp = new ChefDuel2AutoJoinSpoon(activityId, userId, 0);
            ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<>();
            for (Integer spoonId : spoonIds) {
                map.put(spoonId, 0);
            }
            tmp.setSpoonMap(map);
            autoJoinSpoonMap.put(userId, tmp);
        }
        ChefDuel2AutoJoinSpoon autoJoinSpoon = autoJoinSpoonMap.get(userId);
        Map<Integer, Integer> spoonMap = autoJoinSpoon.getSpoonMap();

        for (Integer spoonId : spoonIds) {
            ChefDuelProto.ChefDuel2SpoonTempMsg.Builder spoon = ChefDuelProto.ChefDuel2SpoonTempMsg.newBuilder();
            spoon.setId(spoonId);
            spoon.setCnt(spoonMap.get(spoonId));
            respMsg.addSpoon(spoon);
        }

        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.U_CHEF_DUEL2_GET_AUTO_JOIN_SPOON, respMsg);
        GamePlayerMgr.sendPacket(userId, pbMsg);

        return 0;
    }

    /**
     * 处理自动回访剩余的汤勺
     *
     * @param userId  用户ID
     * @param records 回访记录
     */
    public void dealAutoJoinSpoonRest(long userId, List<ChefDuelProto.ChefDuel2SpoonTempMsg> records) {
        if (records.size() == 4 && autoJoinSpoonMap.containsKey(userId)) { // 未自动回访的汤勺， 汤勺类型数量为3
            Property returns = new Property();
            ChefDuel2AutoJoinSpoon spoon = autoJoinSpoonMap.get(userId);
            if (spoon.getSpoonMap() != null) {
                for (Map.Entry<Integer, Integer> kv : spoon.getSpoonMap().entrySet()) {
                    int spoonId = kv.getKey();
                    int spoonCnt = kv.getValue();
                    if (spoonCnt > 0) {
                        returns.addProperty(spoonId, spoonCnt);
                    }
                }
                spoon.setIsReturn(1);
                if (returns.isNothing()) { // 没有需要返还的汤勺无须发邮件
                    return;
                }
            } else {
                return;
            }

            UserInfo userInfo = UserMgr.getUserInfo(userId);
            String language = LanguageType.LANGUAGE_DEFAULT;
            if (null != userInfo) {
                language = userInfo.getLanguage();
            }

            List<Integer> spoonIds = new ArrayList<>();
            Map<Integer, Integer> spoonMap = new HashMap<>();
            for (ChefDuelProto.ChefDuel2SpoonTempMsg record : records) { // 120463 120464 120465
                spoonIds.add(record.getId());
                spoonMap.put(record.getId(), record.getCnt());
            }
            Collections.sort(spoonIds);
            String title = MultipleLanguageMgr.getContent(MailManager.CHEFDUEL_BANQUET_MAIL_TITLE_1, language);
            String content = StringUtils.format(MultipleLanguageMgr.getContent(MailManager.CHEFDUEL_BANQUET_MAIL_CONTENT_1, language),
                    spoonMap.get(spoonIds.get(0)), spoonMap.get(spoonIds.get(1)), spoonMap.get(spoonIds.get(2)), spoonMap.get(spoonIds.get(3)));
            MailManager.sendMail(userId, eMailType.SYSTEM.getValue(), returns.toHelperString(), content, title);
        }
    }

    /**
     * 开始自动回访流程
     *
     * @param reqMsg reqMsg
     */
    public void startAutoJoin(ChefDuelProto.CrossChefDuel2AutoJoinInfoMsg reqMsg) {
        long guestId = reqMsg.getGuestId();
        int spoonId = reqMsg.getSpoonId();
        if (checkSpoonCnt(guestId, spoonId, reqMsg)) {
            logger.info("访客未设置该类型的自动回访汤勺，无法自动回访。 访客活动ID:{} 访客ID:{} 摊主活动ID:{} 摊主ID:{} 汤勺ID:{}",
                    reqMsg.getGuestActivityId(), guestId, reqMsg.getHostActivityId(), reqMsg.getHostId(), spoonId);
            return;
        }

        ChefDuel2AutoJoinSpoon spoon = autoJoinSpoonMap.get(guestId);
        ConcurrentHashMap<Integer, Integer> spoonMap = spoon.getSpoonMap();
        if (spoonMap != null && spoonMap.get(spoonId) == 0) {
            logger.info("访客未设置该类型的自动回访汤勺，无法自动回访。 访客活动ID:{} 访客ID:{} 摊主活动ID:{} 摊主ID:{} 汤勺ID:{}",
                    reqMsg.getGuestActivityId(), guestId, reqMsg.getHostActivityId(), reqMsg.getHostId(), spoonId);
            return;
        }

        long hostId = reqMsg.getHostId();
        ChefDuelProto.CrossChefDuel2GetTasteTableCntMsg.Builder req =
                ChefDuelProto.CrossChefDuel2GetTasteTableCntMsg.newBuilder();
        req.setActivityId(reqMsg.getHostActivityId());
        req.setAutoJoinInfo(reqMsg);
        if(activityInfo.getActivityId() != req.getActivityId()){
            UserInfo infoInRAM = UserMgr.getUserInfoInRAM(guestId);
            if(infoInRAM != null){
                req.setUserBaseInfo(PlayerPb.parsePlayerBaseTempMsg(infoInRAM));
            }
        }
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_CHEF_DUEL2_GET_TASTE_TABLE_CNT, req);
        GamePlayerMgr.sendPacket(guestId, pbMsg);
    }

    /**
     * 检查自动回访的汤勺是否足够
     *
     * @param userId  用户ID
     * @param spoonId 汤勺ID
     * @return ret
     */
    private boolean checkSpoonCnt(long userId, int spoonId, ChefDuelProto.CrossChefDuel2AutoJoinInfoMsg autoJoinInfo) {
        int guestActivityId = autoJoinInfo.getGuestActivityId();
        int hostActivityId = autoJoinInfo.getHostActivityId();
        long guestId = autoJoinInfo.getGuestId();
        long hostId = autoJoinInfo.getHostId();
        if (!autoJoinSpoonMap.containsKey(userId)) { // todo 会不会太频繁了
            logger.info("访客未设置自动回访汤勺，无法自动回访。 访客活动ID:{} 访客ID:{} 摊主活动ID:{} 摊主ID:{} 汤勺ID:{}", guestActivityId, guestId,
                    hostActivityId, hostId, spoonId);
            return true;
        }

        ChefDuel2AutoJoinSpoon spoon = autoJoinSpoonMap.get(userId);
        ConcurrentHashMap<Integer, Integer> spoonMap = spoon.getSpoonMap();
        if (spoonMap == null || !spoonMap.containsKey(spoonId)) {
            logger.info("访客未设置该类型的自动回访汤勺，无法自动回访。 访客活动ID:{} 访客ID:{} 摊主活动ID:{} 摊主ID:{} 汤勺ID:{}", guestActivityId,
                    guestId, hostActivityId, hostId, spoonId);
            return true;
        }

        return spoonMap.get(spoonId) <= 0;
    }

    /**
     * 正式进行试吃
     *
     * @param reqMsg reqMsg
     */
    public void autoJoinTaste(ChefDuelProto.CrossChefDuel2SyncTasteTableCntMsg reqMsg) {
        ChefDuelProto.CrossChefDuel2AutoJoinInfoMsg autoJoinInfo = reqMsg.getAutoJoinInfo();
        int cnt = reqMsg.getCnt();
        long guestId = autoJoinInfo.getGuestId();
        int spoonId = autoJoinInfo.getSpoonId();

        Object lock = getLock(guestId);
        ChefDuelProto.CrossChefDuel2AutoJoinTasteMsg.Builder req =
                ChefDuelProto.CrossChefDuel2AutoJoinTasteMsg.newBuilder();
        long hostId = autoJoinInfo.getHostId();
        synchronized (lock) {
            if (checkSpoonCnt(guestId, spoonId, autoJoinInfo)) {
                return;
            }

            if (cnt == 0) {
                logger.info("摊主可试吃数量为0，结束自动回访。 访客活动ID:{} 访客ID:{} 摊主活动ID:{} 摊主ID:{} 汤勺ID:{}", autoJoinInfo.getGuestActivityId(),
                        guestId, autoJoinInfo.getHostActivityId(), autoJoinInfo.getHostId(), spoonId);
                return;
            }

            ChefDuel2AutoJoinSpoon spoon = autoJoinSpoonMap.get(guestId);
            ConcurrentHashMap<Integer, Integer> spoonMap = spoon.getSpoonMap();
            int spoonCnt = Math.min(spoonMap.get(spoonId), cnt); // 玩家汤勺数和可试吃数取最小值
            // 预扣除汤勺数，正式自动回访
            spoon.modifySpoonCnt(spoonId, -spoonCnt);
            req.setSpoonCnt(spoonCnt);
        }
        req.setActivityId(autoJoinInfo.getHostActivityId());
        req.setAutoJoinInfo(autoJoinInfo);
        req.setGuestServerId(GameServer.getInstance().getServerId());
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_CHEF_DUEL2_AUTO_JOIN_TASTE, req);
        GamePlayerMgr.sendPacket(hostId, pbMsg);
    }

    /**
     * 处理自动回访数据
     *
     * @param reqMsg reqMsg
     */
    public void dealAutoJoinResult(ChefDuelProto.CrossChefDuel2SyncAutoJoinResultMsg reqMsg) {
        ChefDuelProto.CrossChefDuel2AutoJoinInfoMsg autoJoinInfo = reqMsg.getAutoJoinInfo();

        long guestId = autoJoinInfo.getGuestId();
        if (reqMsg.hasRestCnt()) { // 归还未使用的汤勺
            int restCnt = reqMsg.getRestCnt();
            int spoonId = autoJoinInfo.getSpoonId();
            if (autoJoinSpoonMap.containsKey(guestId)) {
                ChefDuel2AutoJoinSpoon spoon = autoJoinSpoonMap.get(guestId);
                spoon.modifySpoonCnt(spoonId, restCnt);
            } else {
                logger.error("有剩余汤勺的情况下，自动回访设置的汤匙数据不应该为空 活动ID:{} 访客ID:{} 剩余汤勺:{}",
                        autoJoinInfo.getGuestActivityId(), guestId, restCnt);
            }
        }

        ChefDuelProto.CrossChefDuel2SyncAutoJoinDataMsg.Builder req =
                ChefDuelProto.CrossChefDuel2SyncAutoJoinDataMsg.newBuilder();
        req.setAutoJoinInfo(autoJoinInfo);
        req.setActivityId(autoJoinInfo.getGuestActivityId());

        // 汤勺数量同步到跨服
        if (autoJoinSpoonMap.containsKey(guestId)) {
            ChefDuel2AutoJoinSpoon spoon = autoJoinSpoonMap.get(guestId);
            for (Map.Entry<Integer, Integer> kv : spoon.getSpoonMap().entrySet()) {
                ChefDuelProto.ChefDuel2SpoonTempMsg.Builder spoonTemp =
                        ChefDuelProto.ChefDuel2SpoonTempMsg.newBuilder();
                spoonTemp.setId(kv.getKey());
                spoonTemp.setCnt(kv.getValue());
                req.addSpoon(spoonTemp);
            }
        }

        // 去跨服生成自动回访记录
        req.setRealCnt(reqMsg.getRealCnt());

        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_CHEF_DUEL2_SYNC_AUTO_JOIN_DATA, req);
        GamePlayerMgr.sendPacket(guestId, pbMsg);
    }

    /**
     * 自动回访收益发邮件
     *
     * @param userId  用户ID
     * @param reward  收益
     * @param spoonId 汤勺ID
     * @param count   回访次数
     */
    public void dealAutoJoinReward(long userId, String reward, int spoonId, int count) {
        if (!StringUtils.isNullOrEmpty(reward)) {
            UserInfo userInfo = UserMgr.getUserInfo(userId);
            String language = LanguageType.LANGUAGE_DEFAULT;
            if (null != userInfo) {
                language = userInfo.getLanguage();
            }

            GoodsInfo goodsInfo = GoodsMgr.getGoodsById(spoonId);
            String goodsName = goodsInfo.getGoodsName();
            if (StringUtils.isNullOrEmpty(goodsName)) {
                goodsName = "";
            }
            String spoonName = ServerLanguageMgr.getContent(goodsName, language);
            Property property = PropertyHelper.parseStringToProperty(reward).goodCountMultiNum(count);
            String title = MultipleLanguageMgr.getContent(MailManager.CHEFDUEL_BANQUET_MAIL_TITLE_3, language);
            String content = StringUtils.format(MultipleLanguageMgr.getContent(MailManager.CHEFDUEL_BANQUET_MAIL_CONTENT_3, language), spoonName, count);
            MailManager.sendMail(userId, eMailType.DAILY.getValue(), property.toHelperString(), content, title);
        }
    }

    public Map<Long, ChefDuelData> getChefDuelDataMap() {
        return chefDuelDataMap;
    }
}
